import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:changxindianzishangwu/cache/local_cache.dart';
import 'package:changxindianzishangwu/dao/dynamic_media_dao.dart';
import 'package:changxindianzishangwu/dao/upload_file_dao.dart';
import 'package:changxindianzishangwu/http/base/http_urls.dart';
import 'package:changxindianzishangwu/model/dynamic_media_model.dart';
import 'package:changxindianzishangwu/util/app_color.dart';
import 'package:changxindianzishangwu/util/colors.dart';
import 'package:changxindianzishangwu/util/medio/picker_method.dart';
import 'package:changxindianzishangwu/util/toast.dart';
import 'package:changxindianzishangwu/widget/app_bar.dart';
import 'package:changxindianzishangwu/widget/asset_widget_builder.dart';
import 'package:common_utils/common_utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_plugin_record/flutter_plugin_record.dart';
import 'package:get/get.dart' as gets;
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:video_thumbnail/video_thumbnail.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';

/**
 * 发送动态页面
 * 2021-07-07
 * alex
 */
class SendDynamicPage extends StatefulWidget {
  SendDynamicPage({Key key, this.type}) : super(key: key);

  int type;

  @override
  _SendDynamicPageState createState() => _SendDynamicPageState(type);
}

class MediaType {
  static const int MEDIA_TEXT = 1; //文字消息
  static const int MEDIA_TEXT_IMAGE = 2; //图文消息
  static const int MEDIA_TEXT_VOICE = 3; //语音消息
  static const int MEDIA_TEXT_VIDEO = 4; //视频消息
  static const int MEDIA_TEXT_FILE = 5; //文件消息
  static const int MEDIA_SHARE_MEG = 6; //SDK分享消息

  static const int MEDIA_VIDEO_LST = 7; //视频略缩图 保存到本地再上传
}

class _SendDynamicPageState extends State<SendDynamicPage> {
  BuildContext _context;
  bool isDisplayingDetail = true;

  //选择对象集合
  List<AssetEntity> assets = List();

  _SendDynamicPageState(this.type);

  int get assetsLength => assets.length;

  //是否显示"添加"按钮
  bool isAdd = true;

  //基础属性 1=文字消息、2=图文消息、3=语音消息、4=视频消息、 5=文件消息 、 6=SDK分享消息
  int type = MediaType.MEDIA_TEXT;

  //输入框监听
  TextEditingController _controller;

  FlutterPluginRecord recordPlugin = new FlutterPluginRecord();

  //录音地址文件
  String filePath = "";

  //录音监听
  bool isVoiceIng = false;

  //播放
  bool isPlaying = false;
  bool isReset = false;
  int _time = 0;

  var _timer;

  //判断是不是正在发送动态
  bool _isNetIng = false;

  @override
  void initState() {
    super.initState();
    _controller = TextEditingController();

    _initRecordMp3();

    ///初始化方法的监听
    recordPlugin.responseFromInit.listen((data) {
      if (data) {
        print("初始化成功");
      } else {
        print("初始化失败");
      }
    });

    /// 开始录制或结束录制的监听
    recordPlugin.response.listen((data) {
      if (data.msg == "onStop") {
        ///结束录制时会返回录制文件的地址方便上传服务器
        print("onStop  文件路径" + data.path);
        filePath = data.path;
        // _time = data.audioTimeLength.toString();
        print("onStop  时长 " + data.audioTimeLength.toString());
      } else if (data.msg == "onStart") {
        isReset = true;
        startTimer();
        print("onStart ----------");
      } else {
        print("--" + data.msg);
      }
    });

    ///录制过程监听录制的声音的大小 方便做语音动画显示图片的样式
    recordPlugin.responseFromAmplitude.listen((data) {
      var voiceData = double.parse(data.msg);
      print("时长---------   ${voiceData}");
    });

    recordPlugin.responsePlayStateController.listen((data) {
      // print("播放路径   " + data.playPath);
      // print("播放状态   " + data.playState);
      if (data.playState == "complete") {
        setState(() {
          isPlaying = false;
        });
      }
      // setState(() {
      //   isPlaying=!isPlaying;
      // });
    });
  }

  /**
   * 输入内容
   */
  _inputContent() {
    return Container(
      child: TextField(
        maxLength: 200,
        controller: _controller,
        maxLines: 5,
        keyboardType: TextInputType.text,
        cursorColor: AppColor.colorTheme,
        style: TextStyle(color: AppColor.colorText85, fontSize: 15),
        decoration: InputDecoration(
            contentPadding: EdgeInsets.zero,
            hintText: "这一刻的想法...",
            hintStyle: TextStyle(color: AppColor.colorHintText, fontSize: 15),
            border: InputBorder.none),
      ),
    );
  }

  ///选择图片或视频展示列表
  Widget get selectedAssetsListView {
    return Expanded(
        child: GridView.builder(
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
                crossAxisSpacing: width(10),
                mainAxisSpacing: width(10)),
            itemCount: !isAdd ? assetsLength : assetsLength + 1,
            itemBuilder: (_, int index) =>
                assetsLength == index && isAdd ? _addImg() : _item(index)));
  }

  ///默认Add图片
  Widget _addImg() {
    return TextButton(
        style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all(AppColor.colorGrey245)),
        onPressed: () {
          selectAssets();
        },
        child: Icon(
          Icons.add,
          color: AppColor.colorGrey193,
        ));
  }

  Widget _item(int index) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
      child: AspectRatio(
        aspectRatio: 1,
        child: Stack(
          children: <Widget>[
            Positioned.fill(child: _selectedAssetWidget(index)),
            AnimatedPositioned(
              duration: kThemeAnimationDuration,
              top: isDisplayingDetail ? 6.0 : -30.0,
              right: isDisplayingDetail ? 6.0 : -30.0,
              child: _selectedAssetDeleteButton(index),
            ),
          ],
        ),
      ),
    );
  }

  Widget _selectedAssetWidget(int index) {
    final AssetEntity asset = assets.elementAt(index);
    return RepaintBoundary(
      child: ClipRRect(
        borderRadius: BorderRadius.circular(8.0),
        child: AssetWidgetBuilder(
          entity: asset,
          isDisplayingDetail: false,
        ),
      ),
    );
  }

  // Widget _assetWidgetBuilder(AssetEntity asset) {
  //   Widget widget;
  //   switch (asset.type) {
  //     case AssetType.audio:
  //       widget = _audioAssetWidget(asset);
  //       break;
  //     case AssetType.video:
  //       widget = _videoAssetWidget(asset);
  //       break;
  //     case AssetType.image:
  //     case AssetType.other:
  //       widget = _imageAssetWidget(asset);
  //       break;
  //   }
  //   return widget;
  // }

  Widget _selectedAssetDeleteButton(int index) {
    return GestureDetector(
      onTap: () => removeAsset(index),
      child: DecoratedBox(
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(5.0),
          color: Colors.white,
        ),
        child: Icon(
          Icons.close,
          color: Colors.grey,
          size: 15.0,
        ),
      ),
    );
  }

  void removeAsset(int index) {
    setState(() {
      assets.removeAt(index);
      if (assets.isEmpty) {
        isDisplayingDetail = false;
      }
      assets.length == (type == MediaType.MEDIA_TEXT_IMAGE ? 9 : 1)
          ? isAdd = false
          : isAdd = true;
    });
  }

  Widget _audioAssetWidget(AssetEntity asset) {
    return ColoredBox(
      color: Colors.red[200],
      child: Stack(
        children: <Widget>[
          AnimatedPositionedDirectional(
            duration: kThemeAnimationDuration,
            top: 0.0,
            start: 0.0,
            end: 0.0,
            bottom: isDisplayingDetail ? 20.0 : 0.0,
            child: Center(
              child: Icon(
                Icons.audiotrack,
                size: isDisplayingDetail ? 24.0 : 16.0,
              ),
            ),
          ),
          AnimatedPositionedDirectional(
            duration: kThemeAnimationDuration,
            start: 0.0,
            end: 0.0,
            bottom: isDisplayingDetail ? 0.0 : -20.0,
            height: 20.0,
            child: Text(
              asset.title ?? '',
              style: const TextStyle(height: 1.0, fontSize: 10.0),
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              textAlign: TextAlign.center,
            ),
          ),
        ],
      ),
    );
  }

  Widget _imageAssetWidget(AssetEntity asset) {
    return Image(
      image: AssetEntityImageProvider(asset, isOriginal: false),
      fit: BoxFit.cover,
    );
  }

  Widget _videoAssetWidget(AssetEntity asset) {
    return Stack(
      children: <Widget>[
        Positioned.fill(child: _imageAssetWidget(asset)),
        ColoredBox(
          color: Colors.grey,
          child: Center(
            child: Icon(
              Icons.video_library,
              color: Colors.white,
              size: isDisplayingDetail ? 24.0 : 16.0,
            ),
          ),
        ),
      ],
    );
  }

  List<PickMethod> get pickMethods {
    return <PickMethod>[
      PickMethod.image(9),
      PickMethod.video(1),
      // PickMethod.audio(1),
    ];
  }

  Future<void> selectAssets() async {
    final PickMethod model =
        pickMethods[type == MediaType.MEDIA_TEXT_IMAGE ? 0 : 1];

    final List<AssetEntity> result = await model.method(context, assets);
    if (result != null) {
      assets = List<AssetEntity>.from(result);
      if (mounted) {
        setState(() {
          assets.length == (type == MediaType.MEDIA_TEXT_IMAGE ? 9 : 1)
              ? isAdd = false
              : isAdd = true;
        });
      }
    }
  }

  _getAssetsFile() {
    _isNetIng = true;

    var _videoStr;

    if (type == MediaType.MEDIA_TEXT_VOICE) {
      ///音频
      ///
      _getMediaNetPath(type, filePath: filePath).then((value) {
        String assets = json.encode(value);
        _releaseDynamic(assets);
      });
    } else {
      ///图片和视频选择  视频还要上传封面
      Iterable<Future<File>> files = assets.map((element) {
        return element.originFile;
      }).toList();
      Future.wait(files).then((value) {
        value.forEach((element) {
          print('-------${element.path}');
        });
        return _getMediaNetPath(type, assetsFile: value);
      }).then((value) {
        if (type == MediaType.MEDIA_TEXT_VIDEO) {
          _videoStr = json.encode(value);
          return getVideoThumbnail(value[0].oUrl);
        } else {
          String assets = json.encode(value);
          _releaseDynamic(assets);
        }
      }).then((value) {
        if (type == MediaType.MEDIA_TEXT_VIDEO) {
          return _getMediaNetPath(MediaType.MEDIA_VIDEO_LST, filePath: value);
        }
      }).then((value) {
        if (type == MediaType.MEDIA_TEXT_VIDEO) {
          String assets = json.encode(value);
          _releaseDynamic(_videoStr, videoImage: assets);
        }
      });
    }
  }

  Future<String> getVideoThumbnail(String videopath) async {
    return await VideoThumbnail.thumbnailFile(
      video: videopath,
      thumbnailPath: (await getTemporaryDirectory()).path,
      imageFormat: ImageFormat.JPEG,
      quality: 40,
    );
  }

  ///上传图片到服务
  Future<List<Images>> _getMediaNetPath(mediaType,
      {List<File> assetsFile, String filePath}) async {
    FormData formData = FormData();
    if (mediaType == MediaType.MEDIA_TEXT_VOICE) {
      // print('---------录音：$filePath');
      //音频
      formData.files.add(MapEntry(
          "files",
          MultipartFile.fromFileSync(filePath,
              filename:
                  "voice_${new DateTime.now().millisecondsSinceEpoch}.mp3")));
    } else if (mediaType == MediaType.MEDIA_VIDEO_LST) {
      // print('---------视频略缩图：$filePath');

      formData.files.add(MapEntry(
          "files",
          MultipartFile.fromFileSync(filePath,
              filename:
                  "image_${new DateTime.now().millisecondsSinceEpoch}.jpg")));
    } else if (mediaType == MediaType.MEDIA_TEXT_IMAGE) {
      // print('上传图片集合长度：${assetsFile.length}');
      Iterable<MapEntry<String, MultipartFile>> maps =
          Iterable.generate(assetsFile.length, (index) {
        List<int> imageBytes = assetsFile[index].readAsBytesSync();
        // print('---------文件流：${imageBytes.length}');

        return MapEntry("files",
            MultipartFile.fromBytes(imageBytes, filename: assets[index].title));
      });
      formData.files.addAll(maps);
    } else if (mediaType == MediaType.MEDIA_TEXT_VIDEO) {
      formData.files.add(MapEntry(
          "files",
          MultipartFile.fromFileSync(assetsFile[0].path,
              filename:
                  "video_${new DateTime.now().millisecondsSinceEpoch}.mp4")));
    }

    DynamicMediaModel value = await UpLoadFileDao.addFile(formData);
    List<Images> asset = [];
    if (value.resultCode == 1) {
      print('上传文件 服务器返回图片所有信息:${json.encode(value)}');

      if (mediaType == MediaType.MEDIA_TEXT_VOICE) {
        ///手动赋值录音长度
        value.data.audios[0].setLength = _time;
      }
      List<Images> asset = _getImagesType(mediaType, value);
      // print('返回数据 返回图片地址${json.encode(asset)}');
      return asset;
      // _releaseDynamic(asset);
    } else {
      EasyLoading.dismiss();
      _isNetIng = false;
      showToast("媒体上传失败");
    }
    return asset;
  }

  _getImagesType(mediaType, DynamicMediaModel value) {
    switch (mediaType) {
      case MediaType.MEDIA_TEXT_IMAGE:
      case MediaType.MEDIA_VIDEO_LST:
        return value.data.images;
      case MediaType.MEDIA_TEXT_VIDEO:
        return value.data.videos;
      case MediaType.MEDIA_TEXT_VOICE:
        return value.data.audios;
    }
  }

  ///发送动态 videoImage=视频第一帧
  void _releaseDynamic(String asset, {String videoImage}) async {
    // print('上传类型：${type}');
    _isNetIng = true;
    print('上传内容：${asset}');
    String key = type == MediaType.MEDIA_TEXT_IMAGE
        ? "images"
        : type == MediaType.MEDIA_TEXT_VIDEO
            ? "videos"
            : "audios";
    try {
      int resultCode = await DynamicMediaDao.sendMediaContent(
          _controller.text, asset.isEmpty ? 1 : type, key, asset,
          videoImage: videoImage);
      EasyLoading.dismiss();

      if (resultCode == 1) {
        showToast("动态发布成功");
        gets.Get.back(result: true);
        return;
      }
      print('-------dismiss');
      showToast("发布动态失败");
      _isNetIng = false;
    } catch (e) {
      _isNetIng = false;
      EasyLoading.dismiss();
      showToast("发布动态失败,请稍后重试");

    }
  }

  @override
  Widget build(BuildContext context) {
    _context = context;

    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: TopAppBar(context, "", isRightTextBtn: true, rightText: "发布",
          rightCallback: () {
        // print('上传类型：$type');
        print('上传内容：录音：$filePath');
        // print('上传内容：列表:${assets.length}');
        FocusScope.of(context).requestFocus(FocusNode());

        print('_isNetIng:${_isNetIng}');
        if (_isNetIng) {
          return;
        }

        if (isVoiceIng) {
          showToast("正在录音，请等等~");
          return;
        }
        if (type == MediaType.MEDIA_TEXT_IMAGE && assets.length > 0) {
          //图片传输 有addimage
          EasyLoading.show(status: "正在发布图片...");

          _getAssetsFile();
          return;
        }
        if (type == MediaType.MEDIA_TEXT_VIDEO && assets.length > 0) {
          //单个视频
          EasyLoading.show(status: "正在发布视频...");
          _getAssetsFile();
          return;
        }
        if (type == MediaType.MEDIA_TEXT_VOICE && !filePath.isEmpty) {
          //音频

          EasyLoading.show(status: "正在发布录音...");
          _getAssetsFile();
          return;
        }
        if (_controller.text.isEmpty) {
          showToast("请输入内容~");
          return;
        }
        EasyLoading.show(status: "正在发布纯文本...");
        _releaseDynamic("");
      }, leftCallBack: () {
        // Navigator.of(context).pop();
        if (assets.isEmpty && filePath.isEmpty && _controller.text.isEmpty) {
          Navigator.of(context).pop();
        } else
          showCupertinoDialog(
              context: context, builder: (context) => getDialog(context));
        // toast("点击");
      }),
      body: Stack(
        children: [
          GestureDetector(
            onTap: () {
              ///软键盘关闭
              FocusScope.of(context).requestFocus(FocusNode());
            },
            child: Container(
              padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
              color: Colors.white,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  _inputContent(),
                  Container(
                    margin: EdgeInsets.only(bottom: width(10)),
                    child: Text(
                      "添加${type == MediaType.MEDIA_TEXT_IMAGE ? "图片" : type == MediaType.MEDIA_TEXT_VIDEO ? "视频" : "语音"}",
                      style: TextStyle(
                          color: AppColor.colorDefaultText, fontSize: 12),
                    ),
                  ),
                  _dynamicContent()
                ],
              ),
            ),
          ),
          _voiceButton(),
        ],
      ),
    );
  }

  CupertinoAlertDialog getDialog(context) {
    return CupertinoAlertDialog(
        content: new SingleChildScrollView(
          child: ListBody(
            children: <Widget>[Text("提示"), Text("是否要返回？"), Text("当前页面内容不会被保存")],
          ),
        ),
        actions: <Widget>[
          CupertinoDialogAction(
            child: Text("确定"),
            onPressed: () {
              Navigator.of(context).pop();
              gets.Get.back();
            },
          ),
          CupertinoDialogAction(
            child: Text("取消"),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
        ]);
  }

  _dynamicContent() {
    return type == MediaType.MEDIA_TEXT_VOICE
        ? _voiceWidget()
        : selectedAssetsListView;
  }

  ///---------------------录音 start---------------------------------------------

  /**
   * 播放录音按钮
   */
  _voiceWidget() {
    return Container(
      width: width(60),
      height: width(60),
      color: AppColor.colorGrey245,
      child: Stack(
        children: [
          Center(
            child: IconButton(
                onPressed: () {
                  if (filePath.isEmpty) {
                    showToast("请先录制");
                    return;
                  }

                  if (isReset) {
                    isReset = false;
                    setState(() {
                      isPlaying = true;
                    });
                    play();
                    return;
                  }
                  setState(() {
                    isPlaying = !isPlaying;
                  });
                  pause();
                },
                icon: Icon(
                  isPlaying
                      ? Icons.pause_circle_outline_rounded
                      : Icons.play_circle_outline_rounded,
                  color: AppColor.colorTheme,
                )),
          ),
          Positioned(
            right: 5,
            bottom: 5,
            child: Text(
              "$_time s",
              style: TextStyle(color: AppColor.colorGrey153, fontSize: 10),
            ),
          )
        ],
      ),
    );
  }

  /**
   *
   * 底部录音界面
   */
  _voiceButton() {
    return type == MediaType.MEDIA_TEXT_VOICE
        ? Positioned(
            bottom: 0,
            child: Container(
              padding: EdgeInsets.only(top: height(10), bottom: height(20)),
              width: MediaQuery.of(context).size.width,
              color: AppColor.colorGrey245,
              child: Column(
                children: [
                  Text(
                    "--------${_durationTransform(_time)}--------",
                    style:
                        TextStyle(fontSize: 12, color: AppColor.colorHintText),
                  ),
                  Container(
                    margin:
                        EdgeInsets.only(top: height(30), bottom: height(20)),
                    child: IconButton(
                        iconSize: width(60),
                        onPressed: () {
                          setState(() {
                            isVoiceIng = !isVoiceIng;
                            if (isVoiceIng) {
                              start();
                            } else
                              stop();
                          });
                        },
                        icon: Image(
                          image: isVoiceIng
                              ? AssetImage('images/ic_voice_btn_ing.png')
                              : AssetImage('images/ic_voice_btn_end.png'),
                        )),
                  ),
                  Text(
                    isVoiceIng
                        ? "点击完成"
                        : filePath.isEmpty
                            ? "点击录制"
                            : "点击重新录制",
                    style:
                        TextStyle(fontSize: 12, color: AppColor.colorHintText),
                  ),
                ],
              ),
            ))
        : Text("");
  }

  void _requestAppDocumentsDirectory() {
//    if(Platform.isIOS){
//      //ios相关代码
//      setState(() {
//        getApplicationDocumentsDirectory().then((value) {
//          String nowDataTimeStr = DateUtil.getNowDateMs().toString();
//          String wavPath = value.path + "/" + nowDataTimeStr + ".wav";
//          startByWavPath(wavPath);
//        });
//      });
//    }else if(Platform.isAndroid){
//      //android相关代码
//    }

    setState(() {
      getApplicationDocumentsDirectory().then((value) {
        String nowDataTimeStr = DateUtil.getNowDateMs().toString();
        // TODO  注意IOS 传递的Mp3路径一定是以 .MP3 结尾
        String wavPath = "";
        if (Platform.isIOS) {
          wavPath = value.path + "/" + nowDataTimeStr + ".MP3";
        } else {
          wavPath = value.path + "/" + nowDataTimeStr;
        }
        startByWavPath(wavPath);
      });
    });
  }

  ///初始化语音录制的方法
  void _initRecordMp3() async {
    print('----------AA');
    recordPlugin.initRecordMp3();
  }

  ///开始语音录制的方法
  void start() async {
    recordPlugin.start();
  }

  ///根据传递的路径进行语音录制
  void startByWavPath(String wavPath) async {
    recordPlugin.startByWavPath(wavPath);
  }

  ///停止语音录制的方法
  void stop() {
    recordPlugin.stop();
  }

  ///播放语音的方法
  void play() {
    recordPlugin.play();
  }

  ///播放指定路径录音文件  url为iOS播放网络语音，file为播放本地语音文件
  void playByPath(String path, String type) {
    recordPlugin.playByPath(path, type);
  }

  ///暂停|继续播放
  void pause() {
    print('--------------录音pause$isPlaying');
    recordPlugin.pausePlay();
  }

  @override
  void dispose() {
    cancelTimer();

    /// 当界面退出的时候是释放录音资源
    recordPlugin.dispose();
    super.dispose();
    print('-------dismiss dispose');
    _isNetIng = false;
    EasyLoading.dismiss();
  }

  void stopPlay() {
    recordPlugin.stopPlay();
  }

  ///---------------------录音 end---------------------------------------------

  ///---------------------计时 start---------------------------------------------

  String _durationTransform(int seconds) {
    var d = Duration(seconds: seconds);
    List<String> parts = d.toString().split(':');
    return '${parts[1]}:${parts[2].substring(0, 2)}';
  }

  void startTimer() {
    int timeD = 1;
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      print('计时中...$_time');
      setState(() {
        _time = timeD;
      });

      if (!isVoiceIng) {
        timer.cancel();
        return;
      }
      if (timeD >= 60 && isVoiceIng) {
        setState(() {
          isVoiceIng = !isVoiceIng;
        });
        timer.cancel(); // 取消重复计时
        return;
      }
      timeD++; // 秒数+1
    });
  }

  void cancelTimer() {
    if (_timer != null) {
      _timer.cancel();
      _timer = null;
    }
  }

  ///---------------------计时 end---------------------------------------------

}
